package es.gesfutbol.web;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import es.gesfutbol.dao.ICombinacioGeneralDao;
import es.gesfutbol.dao.ICombinacioPropiaDao;
import es.gesfutbol.dao.IEquipEnPenyistaDao;
import es.gesfutbol.dao.IPartitDeQuinielaDao;
import es.gesfutbol.dao.IPenyaDao;
import es.gesfutbol.dao.IPenyistaDao;
import es.gesfutbol.dao.IPronosticDao;
import es.gesfutbol.dao.IQuinielaDao;
import es.gesfutbol.dao.IUsuariRegistratDao;
import es.gesfutbol.domini.implementacio.CombinacioGeneral;
import es.gesfutbol.domini.implementacio.CombinacioPropia;
import es.gesfutbol.domini.implementacio.EquipEnPenyista;
import es.gesfutbol.domini.implementacio.PartitDeQuiniela;
import es.gesfutbol.domini.implementacio.Penya;
import es.gesfutbol.domini.implementacio.Penyista;
import es.gesfutbol.domini.implementacio.Pronostic;
import es.gesfutbol.domini.implementacio.Quiniela;
import es.gesfutbol.domini.implementacio.UsuariRegistrat;
import es.gesfutbol.util.PosicioQuinielaComparator;
import es.gesfutbol.web.backbean.PronosticsBackBean;

public class PronosticsController  extends MultiActionController {
	
	private IPenyaDao penyaDao;
	private IPenyistaDao penyistaDao;	
	private IUsuariRegistratDao usuariRegistratDao;
	private IQuinielaDao quinielaDao;
	private IPartitDeQuinielaDao partitDeQuinielaDao;
	private IEquipEnPenyistaDao equipEnPenyistaDao;
	private ICombinacioPropiaDao combinacioPropiaDao;
	private ICombinacioGeneralDao combinacioGeneralDao;
	private IPronosticDao pronosticDao;
	
	public IPenyistaDao getPenyistaDao() {
		return penyistaDao;
	}

	public void setPenyistaDao(IPenyistaDao penyistaDao) {
		this.penyistaDao = penyistaDao;
	}

	public IUsuariRegistratDao getUsuariRegistratDao() {
		return usuariRegistratDao;
	}

	public void setUsuariRegistratDao(IUsuariRegistratDao usuariRegistratDao) {
		this.usuariRegistratDao = usuariRegistratDao;
	}
	
	public IQuinielaDao getQuinielaDao(){
		return quinielaDao;
	}
	
	public void setQuinielaDao(IQuinielaDao quinielaDao){
		this.quinielaDao = quinielaDao;
	}
	
	public IPartitDeQuinielaDao getPartitDeQuinielaDao(){
		return partitDeQuinielaDao;
	}
	
	public void setPartitDeQuinielaDao(IPartitDeQuinielaDao partitDeQuinielaDao){
		this.partitDeQuinielaDao = partitDeQuinielaDao;
	}
	
	public IPenyaDao getPenyaDao() {
		return penyaDao;
	}

	public void setPenyaDao(IPenyaDao penyaDao) {
		this.penyaDao = penyaDao;
	}
	
	public IEquipEnPenyistaDao getEquipEnPenyistaDao() {
		return equipEnPenyistaDao;
	}

	public void setEquipEnPenyistaDao(IEquipEnPenyistaDao equipEnPenyistaDao) {
		this.equipEnPenyistaDao = equipEnPenyistaDao;
	}
	
	public ICombinacioPropiaDao getCombinacioPropiaDao() {
		return combinacioPropiaDao;
	}

	public void setCombinacioPropiaDao(ICombinacioPropiaDao combinacioPropiaDao) {
		this.combinacioPropiaDao = combinacioPropiaDao;
	}

	public ICombinacioGeneralDao getCombinacioGeneralDao() {
		return combinacioGeneralDao;
	}

	public void setCombinacioGeneralDao(ICombinacioGeneralDao combinacioGeneralDao) {
		this.combinacioGeneralDao = combinacioGeneralDao;
	}

	public IPronosticDao getPronosticDao() {
		return pronosticDao;
	}

	public void setPronosticDao(IPronosticDao pronosticDao) {
		this.pronosticDao = pronosticDao;
	}

	public ModelAndView init(HttpServletRequest request,
			HttpServletResponse response)throws Exception{
		
		//Busquem els equips del penyista
		String sAlies = request.getParameter("alies");
		UsuariRegistrat usuari = usuariRegistratDao.findByAlies(sAlies);
		 
		Penyista penyista = penyistaDao.findByIdUsuari(usuari.getIdUsuari());
		penyista = penyistaDao.deproxy(penyista);
		
		List<EquipEnPenyista> equips = equipEnPenyistaDao.findByIdPenyistaDeproxy(penyista.getIdPenyista());
		
		//Busquem les combinacions que ha de fer
		Penya penya = penyista.getPenya();
		penya  = penyaDao.deproxy(penya);
		
		Set<CombinacioGeneral> combGenerals = penya.getCombGenerals();				
		Set<CombinacioPropia> combPropies = penya.getCombPropies();
		
		//Busquem la travessa de la jornada
		Quiniela quiniela = quinielaDao.findQuinielaActiva();
		quiniela = quinielaDao.deproxy(quiniela);
		Set<PartitDeQuiniela> partits = quiniela.getPartits();
		List<PartitDeQuiniela> partitsDeQuiniela = new ArrayList<PartitDeQuiniela>(partits);
		partitsDeQuiniela = partitDeQuinielaDao.deproxylist(partitsDeQuiniela);
		Collections.sort(partitsDeQuiniela, new PosicioQuinielaComparator());
		
		Set<CombinacioGeneral> setCG = new HashSet<CombinacioGeneral>();
		Set<CombinacioPropia> setCP = new HashSet<CombinacioPropia>();
		//busquem els pronostics que ja ha fet el penyista sobre els partits de la travessa		
		Iterator<PartitDeQuiniela> itPDQ = partitsDeQuiniela.iterator();
		while(itPDQ.hasNext()){
			PartitDeQuiniela pDQ = itPDQ.next();
			List<Pronostic> pronostics = pronosticDao.findByPartitQuinielaIPenyista(pDQ.getIdPartitDeQuiniela(), penyista.getIdPenyista());
			
			if(pronostics!=null){
				Set<Pronostic> setPronostic = new HashSet<Pronostic>(pronostics);
				setPronostic = pronosticDao.deproxyCombinacions(setPronostic);
				pDQ.setPronostics(setPronostic);
				
				//fiquem els pronostics a la combinacio general que correspon
				
				Iterator<CombinacioGeneral> itCombGen = combGenerals.iterator();
				while(itCombGen.hasNext()){
					Set<Pronostic> pronDeCombinacioG = new HashSet<Pronostic>(); //set per guardar els pronostics d'una determinada combinacioGeneral
					CombinacioGeneral cG = itCombGen.next();
					Iterator<Pronostic> itPron = pronostics.iterator();
					while(itPron.hasNext()){
						Pronostic p = itPron.next();
						if(p.getCombinacioGeneral()!=null){
							if(p.getCombinacioGeneral().getIdCombinacioGeneral() == cG.getIdCombinacioGeneral()){
								pronDeCombinacioG.add(p);
							}
						}
					}
					cG.setPronostics(pronDeCombinacioG);
					setCG.add(cG);
				}
				
				//fiquem els pronostics a la combinacio propia que correspon
				Iterator<CombinacioPropia> itCombPro = combPropies.iterator();
				while(itCombPro.hasNext()){
					Set<Pronostic> pronDeCombinacioP = new HashSet<Pronostic>(); //set per guardar els pronostics d'una determinada combinacioGeneral
					CombinacioPropia cP = itCombPro.next();
					Iterator<Pronostic> itPron2 = pronostics.iterator();
					while(itPron2.hasNext()){
						Pronostic p = itPron2.next();
						if(p.getCombinacioPropia()!=null){
							if(p.getCombinacioPropia().getIdCombinacioPropia() == cP.getIdCombinacioPropia()){
								
								pronDeCombinacioP.add(p);
							}
						}
					}
					cP.setPronostics(pronDeCombinacioP);
					setCP.add(cP);
				}
			
			}
			
		}
		
		ModelMap model = new ModelMap();
		model.put("llistatEquips", equips);
		model.put("llistatGenerals", setCG);
		model.put("llistatPropies", setCP);
		model.put("quinielaActiva", quiniela);
		model.put("llistatPartits", partitsDeQuiniela);
		return new ModelAndView("usuari/pronostics", model);		
	}
	
	public ModelAndView showCombinacio(HttpServletRequest request,
			HttpServletResponse response)throws Exception{
		
		//Busquem els equips del penyista
		String sAlies = request.getParameter("alies");
		UsuariRegistrat usuari = usuariRegistratDao.findByAlies(sAlies);
		 
		Penyista penyista = penyistaDao.findByIdUsuari(usuari.getIdUsuari());
		penyista = penyistaDao.deproxy(penyista);
		
		List<EquipEnPenyista> equips = equipEnPenyistaDao.findByIdPenyistaDeproxy(penyista.getIdPenyista());
		
		String tipusCombinacio = null;
		Object combinacio = null;
		
		//Busquem la combinació a pronosticar
		if(request.getParameter("idCombinacioPropia")!=null){
			Long idCombPropia = Long.parseLong(request.getParameter("idCombinacioPropia"));
			combinacio = (CombinacioPropia)combinacioPropiaDao.findById(idCombPropia);
			tipusCombinacio = "Propia"; 
		}	
		
		if(request.getParameter("idCombinacioGeneral")!=null){
			Long idCombGeneral = Long.parseLong(request.getParameter("idCombinacioGeneral"));
			combinacio = (CombinacioGeneral)combinacioGeneralDao.findById(idCombGeneral);
			tipusCombinacio = "General";
		}
			
		//Busquem la travessa de la jornada
		Quiniela quiniela = quinielaDao.findQuinielaActiva();
		quiniela = quinielaDao.deproxy(quiniela);
		Set<PartitDeQuiniela> partits = quiniela.getPartits();
		List<PartitDeQuiniela> partitsDeQuiniela = new ArrayList<PartitDeQuiniela>(partits);
		partitsDeQuiniela = partitDeQuinielaDao.deproxylist(partitsDeQuiniela);
		Collections.sort(partitsDeQuiniela, new PosicioQuinielaComparator());
		
		
		ModelMap model = new ModelMap();
		model.put("llistatEquips", equips);		
		model.put("combinacio", combinacio);
		model.put("tipusCombinacio", tipusCombinacio);
		model.put("quinielaActiva", quiniela);
		model.put("llistatPartits", partitsDeQuiniela);
		return new ModelAndView("usuari/mostrarPronostics", model);
		
	}
	
	public ModelAndView savePronostics(HttpServletRequest request,
			HttpServletResponse response, PronosticsBackBean pronostics)throws Exception{
		
		String sAlies = pronostics.getAliesPenyista();
		UsuariRegistrat usuari = usuariRegistratDao.findByAlies(sAlies);		
		Penyista penyista = penyistaDao.findByIdUsuari(usuari.getIdUsuari());
		//penyista = penyistaDao.deproxy(penyista);
		
		CombinacioPropia combinacioPropia = null;
		CombinacioGeneral combinacioGeneral = null;
		
		//String tipusCombinacio = pronostics.getTipusCombinacio();
		
		if(pronostics.getTipusCombinacio().compareTo("Propia")==0){
			combinacioPropia = combinacioPropiaDao.findById(pronostics.getIdCombinacioPropia());
		}else{
			combinacioGeneral = combinacioGeneralDao.findById(pronostics.getIdCombinacioGeneral());
		}
		
		Quiniela quiniela = quinielaDao.findQuinielaActiva();
		Long idQuiniela = quiniela.getIdQuiniela();
		
		List<PartitDeQuiniela> partits = new ArrayList<PartitDeQuiniela>(15);
				
		for (int i = 0; i < 16; i ++){
			partits.add(i, partitDeQuinielaDao.findByQuinielaIPosicio(idQuiniela, i+1));
		}
		List<Integer> lp = new ArrayList<Integer>();
		lp.add(pronostics.getP1());
		lp.add(pronostics.getP2());
		lp.add(pronostics.getP3());
		lp.add(pronostics.getP4());
		lp.add(pronostics.getP5());
		lp.add(pronostics.getP6());
		lp.add(pronostics.getP7());
		lp.add(pronostics.getP8());
		lp.add(pronostics.getP9());
		lp.add(pronostics.getP10());
		lp.add(pronostics.getP11());
		lp.add(pronostics.getP12());
		lp.add(pronostics.getP13());
		lp.add(pronostics.getP14());
		lp.add(pronostics.getP15());
		
		List<Pronostic> pronosticsFets = new ArrayList<Pronostic>();
		
		int contador = 0;
		for(Integer iP : lp){
		
				Pronostic p1 = new Pronostic();
				if(combinacioPropia != null){
					p1 = pronosticDao.findByCombinacioPropiaIPartitQuinielaIPenyista(combinacioPropia.getIdCombinacioPropia(), 
							partits.get(contador).getIdPartitDeQuiniela(), penyista.getIdPenyista());
					if(p1==null) p1 = new Pronostic();
					p1.setCombinacioPropia(combinacioPropia);
					
				}else{
					p1 = pronosticDao.findByCombinacioGeneralIPartitQuinielaIPenyista(combinacioGeneral.getIdCombinacioGeneral(), 
							partits.get(contador).getIdPartitDeQuiniela(), penyista.getIdPenyista());
					if(p1==null) p1 = new Pronostic();
					p1.setCombinacioGeneral(combinacioGeneral);
				}
				
				p1.setPartitDeQuiniela(partits.get(contador));
				p1.setPenyista(penyista);
				p1 = fixarPronostic(p1,iP);
				pronosticsFets.add(p1);
				pronosticDao.saveOrUpdate(p1);
	
			contador++;
		}				

		return new ModelAndView("redirect:init.htm?alies=" + sAlies);
	}
	
	public Pronostic fixarPronostic(Pronostic p, Integer valor)	{
		
		switch(valor){
		case 0: //buit
			p.setUn(false);
			p.setIx(false);
			p.setDos(false);				
			break;
		case 1: //1
			p.setUn(true);
			p.setIx(false);
			p.setDos(false);				
			break;
		case 2: //X
			p.setUn(false);
			p.setIx(true);
			p.setDos(false);				
			break;
		case 3: //2
			p.setUn(false);
			p.setIx(false);
			p.setDos(true);				
			break;
		case 4: //1X
			p.setUn(true);
			p.setIx(true);
			p.setDos(false);				
			break;
		case 5: //12
			p.setUn(true);
			p.setIx(false);
			p.setDos(true);				
			break;
		case 6: //X2
			p.setUn(false);
			p.setIx(true);
			p.setDos(true);				
			break;
		case 7: //1X2
			p.setUn(true);
			p.setIx(true);
			p.setDos(true);				
			break;
		}
		return p;
	}
	
}